#include <cbm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <conio.h>
//#include <stdbool.h>

#include "Directory.h"
#include "Buffers.h"
#include "Trim.h"
#include "Splitter.h"
#include "cbm_dir.h"
#include "Drives.h"

#pragma code-name("DIRECTORYCODE");
#pragma rodata-name("DIRECTORYCODE");

// Convert a file-type code-number into the type's initial letter.
// d - DELeted, but closed
// S - SEQuential
// P - PRoGram
// U - USeR-made format
// R - RELative
// C - CBM partition
// D - DIRectory
// L - soft-LiNK
// V - VoRPal fast-loading
// O - any Other type
char __fastcall__ getFileType(unsigned char type)
{
	if(type < CBM_T_OTHER) return "dSPURCDLV"[type];
	return 'O';
}


unsigned char displayDirectory(unsigned char driveIndex)
{
	unsigned char r = 0, c = 0;
	struct cbm_dirent entry;
	char showSize = 1;
	drive_t *drive = &drives[driveIndex];
	tokenCollection_t *collection = NULL;
	static char buffer[256];
	parsedPath_t *path = NULL;


	memset(buffer, 0, sizeof(buffer));
	strcpy(buffer, buffer3);

//printf("\nGot here 1. %04X", splitString);
//cgetc();

	collection = splitString(buffer);

//printf("\nGot here 2.");
//cgetc();


	if(collection->count == 1 || collection->count == 2)
	{
		if(collection->count == 2)
		{
			path = parsePath(1, collection, driveIndex);

			//printf("\ncollection->tokens[1].text: %s", collection->tokens[1].text);
		}
		else
		{
			path = (parsedPath_t *)malloc(sizeof(parsedPath_t));
			memset(path, 0, sizeof(path));
			path->device = drive->device;
			path->drive = drive->drive;
			strcpy(path->path, drive->path);
			strcpy(path->file, "*");
		}

		//printf("\npath->device: %u", path->device);
		//printf("\npath->drive : %u", path->drive);
		//printf("\npath->path  : %s", path->path);
		//printf("\npath->file  : %s", path->file);

		//cgetc();

		driveIndex = getDrive(path->device);
		if(driveIndex == 0xFF) 
		{
			printf("\nUnknown device: %u", path->device);
			free(collection);
			free(path);
			return 1;
		}
		drive = &drives[driveIndex];

		//printf("\ndriveIndex: %d", driveIndex);
		//cgetc();

		memset(buffer2, 0, sizeof(buffer2));

		if(drive->type == CBM15x1)
		{
			sprintf(buffer2, "$%1u:%s", path->drive, (path->file[0] == 0 ? "*" : path->file));
		}
		else if(drive->type != VICE)
		{
			sprintf(buffer2, "$%1u%s:%s", path->drive, path->path, (path->file[0] == 0 ? "*" : path->file));
		}
		else
		{
			sprintf(buffer2, "$%1u:%s", path->drive, path->path);
		}

		//printf("\n%s", buffer2);
		//cgetc();

		cbm_open(15, path->device, 15, "");

		//printf("\nAfter open command channel.");
		//cgetc();

		r = cbm_opendir2(1, path->device, buffer2);

		//printf("\nOpen dir: %d", r);
		//cgetc();

		if(r == 0)
		{

			if(drives[getDrive(path->device)].type != CBM15x1)
			{
				printf("\nDirectory of %d#%d:%s", path->device, path->drive, path->path);
			}
			else
			{
				printf("\nDirectory of %d#%d:", path->device, path->drive);
			}
			++c;

			//printf("\ncbm_readdir: %04X", cbm_readdir);
			//cgetc();
		
			// Header
			r = cbm_readdir(1, &entry);

			//printf("\nRead Dir Entry: %d", r);
			//cgetc();

			if(r == 0)
			{
				printf("\n%s\n", entry.name);
				//cgetc();
				c+=2;

				while(cbm_readdir(1, &entry) != 2)
				{
					printf("\n%05u %-16s %c", entry.size, entry.name, getFileType(entry.type));
					//cgetc();
					++c;
					if(c == 24)
					{
						printf("\n                            -- pause --");
						r = cgetc();
						if(r == CH_STOP) { showSize = 0; break; }
						c = 0;
					}
					if(kbhit() && cgetc() == CH_STOP) { showSize = 0; break; }
				}

				if(showSize) printf("\n\n%u blocks free", entry.size);
				cbm_close(1);
				cbm_close(15);

				return 0;
			}
		}
		else
		{
			cbm_read(15, buffer1, sizeof(buffer1));
			printf("\n%s", buffer1);
			cbm_close(1);
			cbm_close(15);
			return r;
		}

	}
	else
	{
		printf("\nusage: dir [pattern]\n");
		return 0;
	}

	cbm_close(1);
	cbm_close(15);

	return 0;
}